package com.zhangmeng.windowportbind;

import com.zhangmeng.windowportbind.dto.PortBind;
import com.zhangmeng.windowportbind.utils.AlertUtils;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.MapValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import java.io.IOException;
import java.util.Map;

import static com.zhangmeng.windowportbind.utils.PortUtils.*;

public class PortApplication extends Application {

    private final ObservableList<Map<String, SimpleStringProperty>> data = FXCollections.observableArrayList();

    private TableView<Map<String, SimpleStringProperty>> tableView;

    private final List<String> columns = List.of("协议", "本地IP", "本地端口", "外部IP", "外部端口", "状态", "pid");

    private VBox vBox;

    private HBox hBox;

    @Override
    public void start(Stage stage) throws IOException {

        initTable();

        AnchorPane anchorPane = new AnchorPane();
        anchorPane.setPrefWidth(1200);
        anchorPane.setPrefHeight(649);

        vBox = new VBox();
        vBox.prefWidthProperty().bind(anchorPane.widthProperty());
        vBox.prefHeightProperty().bind(anchorPane.heightProperty());

        hBox = new HBox(10);
        hBox.prefWidthProperty().bind(anchorPane.widthProperty());

        TextField textField = new TextField();
        textField.setPromptText("端口号");
        textField.setPrefHeight(30);
        Label label = new Label("端口号");
        label.setPrefHeight(30);
        hBox.getChildren().addAll(label, textField);

        Button button = new Button("查询");
        button.setPrefHeight(30);
        button.setOnAction(event -> {
            String port = textField.getText();
            List<PortBind> usedPorts = new ArrayList<>();
            if (port.isEmpty()) {
                usedPorts = getUsedPorts();
                flushTable(usedPorts);
                return;
            }

            if (port.matches("\\d+")) {
                usedPorts = getQueryPort(Integer.parseInt(port));
                flushTable(usedPorts);
            }
        });
        hBox.getChildren().add(button);

        vBox.getChildren().add(hBox);

        tableView = new TableView<>();
        tableView.setEditable(false);
        tableView.setItems(data);
        tableView.prefWidthProperty().bind(anchorPane.widthProperty());
        tableView.prefHeightProperty().bind(anchorPane.heightProperty());

        columns.forEach(col -> {
            TableColumn<Map<String, SimpleStringProperty>, String> column = new TableColumn<>(col);
            // 数据绑定‌:ml-citation{ref="1,3" data="citationList"}
            column.setCellValueFactory(new MapValueFactory(col));
            // 启用单元格编辑‌:ml-citation{ref="4,5" data="citationList"}
            column.setCellFactory(TextFieldTableCell.forTableColumn());
            column.prefWidthProperty().bind(tableView.widthProperty().divide(columns.size()));
            tableView.getColumns().add(column);
        });

        ContextMenu contextMenu = new ContextMenu();
        MenuItem menuItem = new MenuItem("结束该端口占用进程");
        menuItem.setOnAction(event -> {
            int selectedIndex = tableView.getSelectionModel().getSelectedIndex();
            Map<String, SimpleStringProperty> selectedItem = tableView.getSelectionModel().getSelectedItem();
            if (selectedItem == null){
                AlertUtils.alert_warning("请先选择要结束的端口");
                return;
            }
            String pid = selectedItem.get("pid").getValue();
            if (pid.isEmpty()){
                AlertUtils.alert_warning("该端口PID为空，无法结束进程");
                return;
            }

            boolean flag = killProcessByPID(Integer.parseInt(pid));

            if (flag){
                AlertUtils.alert_msg("端口占用进程已结束");
                data.remove(selectedIndex);
            }else{
                AlertUtils.alert_warning("端口占用进程结束失败");
            }
        });
        contextMenu.getItems().add(menuItem);
        tableView.setContextMenu(contextMenu);


        vBox.getChildren().add(tableView);
        anchorPane.getChildren().add(vBox);

        Scene scene = new Scene(anchorPane);
        stage.setTitle("端口占用查看工具");
        stage.setScene(scene);
        stage.show();
    }

    private void initTable() {
        List<PortBind> usedPorts = getUsedPorts();
        flushTable(usedPorts);
    }

    public void flushTable(List<PortBind> usedPorts) {
        data.clear();
        for (PortBind portBind : usedPorts) {
            Map<String, SimpleStringProperty> row = new HashMap<>();
            row.put("协议", new SimpleStringProperty(portBind.getProtocol()));
            row.put("本地IP", new SimpleStringProperty(portBind.getLocalIp()));
            row.put("本地端口", new SimpleStringProperty(String.valueOf(portBind.getLocalPort())));
            row.put("外部IP", new SimpleStringProperty(portBind.getRemoteIp()));
            row.put("外部端口", new SimpleStringProperty(String.valueOf(portBind.getRemotePort())));
            row.put("状态", new SimpleStringProperty(portBind.getState()));
            row.put("pid", new SimpleStringProperty(portBind.getPid()));
            data.add(row);
        }
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}